package net.thermetics.fx.features;

import java.io.PrintStream;

/**
 * Interface describing an individual Feature Component. A Feature Component
 * has its own URL patterns that it operates on, and a single JavaScript entry
 * point to run the Component. A Component may be either scoped to the page
 * (basically a userscript) or a widget, which runs on appspot in an iframe.
 * <br/><br/>
 * All components are given a JavaScript API that gives them access to jQuery and
 * TFX-specific functions.  
 * @author projectmoon
 *
 */
public interface Component {	
	/**
	 * Verifies that this component is not in an inconsistent state.
	 * An exception will be thrown if an error is detected within the
	 * component. The component verifies that its parent feature contains
	 * it. It also checks the permissions within its code and verifies that
	 * the component has requested these permisisons in the component configuration.
	 */
	public void verify();
	
	/**
	 * A unique identifier property that identifies this component to its parent feature.
	 * @return The ID.
	 */
	public String getId();
	
	/**
	 * Sets the component identifier.
	 * @param id
	 */
	public void setId(String id);
	
	/**
	 * Specifies the URL to retrieve the code for this component. This property
	 * is separate from but related to the content type. The TFX web application
	 * will read in the text found at the code URL and then serve it up according
	 * to the mime type found in the contentType property.
	 * <br/><br/>
	 * If this property is not specifically set, the code URL is constructed from
	 * the component identifier.
	 * @return The code URL.
	 */
	public String getCodeUrl();
	
	/**
	 * Sets the code URL. This will override the default behavior of getCodeUrl(), as
	 * detailed above.
	 * @param url
	 */
	public void setCodeUrl(String url);
	
	/**
	 * Read-only property that returns the mime type for this component.
	 * @return The mime type.
	 */
	public String getContentType();
	
	/**
	 * Renders this component to the specified output stream. The way the
	 * component is rendered depends on the Component's underlying implementation.
	 * Scoped components will be rendered as JavaScript code. Widgets will be
	 * rendered as iframes.
	 * <br/><br/>
	 * This only outputs the text found at the code URL. It does not handle serving
	 * up of the content type. The passed {@link PrintStream} is not closed after
	 * this method ends, so user code must manually close the PrintStream if necessary.
	 * @param out
	 */
	public String render();
}
